<!--
*@Author: QWP
*@Description: 自定义列表展示列
*@Date: 2024-07-08 17:04:38
-->
<template>
  <u-drawer
    title="自定义列"
    placement="right"
    v-bind="$attrs"
    @close="dialogClose">
    <a-layout class="f-h-100">
      <u-collapsed-sider :canExpand="false"
        width="400px"
        style="overflow: auto">
        <u-busi-card v-for="item in collapses"
          :title="item.label"
          class="f-margin-b16">
          <template #extra>
            <a-checkbox v-model:checked="checkAllData[item.activeKey]" 
              :indeterminate="(checkData[item.activeKey] || []).length != 0 && !checkAllData[item.activeKey]"
              @change="onCheckAllChange(item.activeKey, checkAllData[item.activeKey], (item['els'] || []))">全选
            </a-checkbox>
          </template>
          <a-checkbox-group v-model:value="checkData[item.activeKey]"
            style="width: 100%">
            <a-row :gutter="[12, 12]">
              <a-col :span="12" v-for="cItem in (item['els'] || [])">
                <a-checkbox :value="cItem['key'] || cItem['dataIndex']"
                  @change="(e) => busiItemChange(item.activeKey, e)">
                  {{  cItem['label'] || cItem['title'] }}
                </a-checkbox>
              </a-col>
            </a-row>
            </a-checkbox-group>
        </u-busi-card>
      </u-collapsed-sider>
      <u-table-content>
        <a-layout class="f-h-100">
          <u-table-header style="padding: 6px 0">
            <a-row align="middle">
              <a-col flex="1">
                <span>已选: {{ getSelNumber }}</span>
              </a-col>
              <a-button type="link" @click="clearAllTable">清空</a-button>
            </a-row>
          </u-table-header>
          <u-table-content class="f-h-100" style="padding: 0; overflow: auto">
            <a-tree class="draggable-tree u-side-tree-custom" 
              v-if="columns.length != 0 && refresh"
              draggable
              block-node
              :tree-data="columns"
              :fieldNames="{ title: 'title', key: 'dataIndex', children: 'children'}"
              show-icon
              :default-expand-all="true"
              :expandedKeys="expandedKeys"
              @drop="onDrop">
              <template #icon="{ dataIndex, selected }">
                <u-icon-font type="icon-a-guizhangzhidu1" />
                <u-icon-font type="icon-a-tuihui1" 
                  class="u-tree-clear-icon"
                  @click="removeItem(dataIndex)"/>
              </template>
            </a-tree>
          </u-table-content>
        </a-layout>
      </u-table-content>
    </a-layout>

    <template #footer>
      <a-row justify="end" class="f-padding-tb8">
        <a-space>
          <u-icon-button itype="save" @click="submit">保存</u-icon-button>
          <u-icon-button itype="close" @click="emits('close')">关闭</u-icon-button>
        </a-space>
      </a-row>
    </template>
  </u-drawer>
</template>

<script lang='ts' setup>
import { ref, reactive, computed, onMounted, h, useAttrs, watch, nextTick } from 'vue' 
import { useLoginStore,  useBaseStore, useTableColStore } from '@/store'
import { storeToRefs } from 'pinia'
import { useRoute, useRouter } from 'vue-router'
import { _IFormEl, _IExtra } from '@/components/common/form/interface';
import { FormInstance, FormItemProps } from 'ant-design-vue';
import { HomeOutlined, FileTextOutlined, UploadOutlined } from '@ant-design/icons-vue';
import { TreeProps } from 'ant-design-vue/es/vc-tree';
import { ColumnProps } from 'ant-design-vue/es/table';
import { _IColumnProps } from '@/components/common/tableEdit/interface.ts'
import { fileCols } from '@/common/model/fileCols'
import { cloneDeep } from 'lodash'
import { numberToText } from '@/common/model/base'
import { alertC, messageC, numberC, isValue } from '@/util/common'
import { initSelEls, TColumns } from './data/colData.ts'

interface Props {
  params?: object,
  keyid?: string
}
const props = withDefaults(defineProps<Props>(), {
  params: {}
})
const route = useRoute()
const attrs = useAttrs()
const { userInfo } = storeToRefs(useLoginStore())
const tableColStore = useTableColStore()
const { storeCols } = storeToRefs(tableColStore)

const emits = defineEmits(['success', 'close'])

// 表单相关信息
const refresh = ref<boolean>(false)
const formRef = ref<FormInstance>()
const checkData = ref({})
const checkAllData = ref({})
const formLoading = ref<boolean>(false)
const expandedKeys = computed(() => columns.value.map(i => i.dataIndex))
const getSelNumber = computed(() => {
  let total = columns.value.filter(i => (i.children || []).length == 0).length;
  total += columns.value.filter(i => (i.children || []).length != 0).map(i => i.children).flat(2).length
  return total
})

const bodyStyle = {
  background: 'rgb(245, 246, 247)'
}

// 初始化需要勾选的字段
const tSelEls = initSelEls()
let collapses = computed(() => tSelEls)

// 确认提交
const submit = async () => {
  tableColStore.setStoreCols(cloneDeep(columns.value))
  emits('close')
}

// 初始化默认保存传递的数据
const initBaseInfo = () => {
  form.value = {
    fkuserid: userInfo.value["userId"],
    fkusername: userInfo.value["name"],
    fkdeptid: userInfo.value["deptId"],
    redeptname: userInfo.value["deptName"],
    ssdeptid: userInfo.value["deptId"],
    ssdeptname: userInfo.value["deptName"],
    fkunitsid: userInfo.value["unitId"],
    unitName: userInfo.value["unitName"],
  }
}

// 全选和取消全选
const onCheckAllChange = (key: string, checked: boolean, els: any[]) => {
  if(checked == true) {
    checkData.value[key] = checked ? els.map(i => i['key'] || i['dataIndex']) : []
    els.forEach(item => {
      busiItemChange(key, { 
        target: {
          checked,
          value: item['key'] || item['dataIndex']
        }
      })
    })
  }
  else {
    checkData.value[key] = []
    if(key == 'base') {
      columns.value = columns.value.filter(i => i.parentKey != key)
    }
    else {
      columns.value = columns.value.filter(i => i.dataIndex != key)
    }
    refreshTree()
  }
}

const refreshTree = () => {
  refresh.value = false;
  nextTick(() => refresh.value = true)
}

// 每一项选择框的点击
const busiItemChange = (activeKey, value) => {
  const { target } = value
  // 取消选择
  if(target.checked == false) {
    removeItem(target.value)
  }
  // 选中
  else {
    let parentBusi = collapses.value.find(i => i.activeKey == activeKey) || {};
    let els = parentBusi['els'] || [];
    let currentItem = els.find(i => (i['key'] || i['dataIndex']) == target.value);
    if(currentItem) {
      const currentResult = { 
        ...currentItem,
        dataIndex: target.value, 
        parentKey: activeKey,
        title: (currentItem['label'] || currentItem['title']) || '', 
        width: (currentItem['width'] || currentItem['minWidth']) || 100, 
      }
      if(activeKey == 'base') {
        columns.value.push(currentResult)
      }
      else {
        let parents = columns.value.find(i => i.dataIndex == activeKey );
        if(!parents) {
          parents = {
            title: parentBusi.label,
            dataIndex: activeKey,
            children: [ currentResult ],
            align: 'center'
          }
          columns.value.push(parents)
        }
        else {
          parents['children'].push(currentResult)
          let pIndex = columns.value.findIndex(i => i.dataIndex == activeKey)
          columns.value.splice(pIndex, 1, parents)
        }
      }
    }
  }

  refreshTree()
}

// 右侧列表数据
const columns = ref<any[]>([])
const onDrop = (info: AntTreeNodeDropEvent) => {
  const dropKey = info.dragNode.key;
  const dropPosition = info.dropPosition;
  const targetKey = info.node.key;

  const data = cloneDeep(columns.value);
  // 一级
  if(!info.dragNode['parent']) {
    let index = data.findIndex(i => i.dataIndex == dropKey);
    let targetIndex = data.findIndex(i => i.dataIndex == targetKey)
    if(targetIndex == -1) {
      return
    }
    data[index]['moveNode'] = 'current'
    if(index != -1) {
      let item = cloneDeep(columns.value[index])
      data.splice(dropPosition == -1 ? 0 : dropPosition, 0, item)
      let currentOldNode = data.findIndex(o => o['moveNode'] == 'current');
      if(currentOldNode != -1) {
        data.splice(currentOldNode, 1)
      }
    }
    columns.value = data;
  }
  // 所有子级
  else {
    const move = (data1) => {
      data1.forEach(oArr => {
        if(oArr['children']) {
          let dragNodeIndex = oArr['children'].findIndex(i => i.dataIndex == dropKey);
          let targetIndex = targetKey == oArr.dataIndex ? 0 : oArr['children'].findIndex(i => i.dataIndex == targetKey)
          if(targetIndex == -1) {
            return
          }
          if(dragNodeIndex != -1) {
            let item = cloneDeep(oArr['children'][dragNodeIndex])
            
            oArr['children'][dragNodeIndex]['moveNode'] = 'current'
            
            let finalIndex = targetIndex > dragNodeIndex ? dragNodeIndex + dropPosition : dragNodeIndex - dropPosition
            finalIndex = finalIndex < 0 ? 0 : finalIndex
            oArr['children'].splice(finalIndex, 0, item)
            let currentOldNodeIndex = oArr['children'].findIndex(o => o['moveNode'] == 'current');
            if(currentOldNodeIndex != -1) {
              oArr['children'].splice(currentOldNodeIndex, 1)
            }
          } else {
            move(data1)
          }
        }
      })
    }
    move(data)
    columns.value = data;
  }
};

// 清除单项数据
const removeItem = (key) => {
  let isDelete = false;

  // 判断是否是父级
  let nodeIndex = columns.value.findIndex(i => i.dataIndex == key);
  if(nodeIndex != -1) {
    checkData.value[key] = []
    checkAllData.value[key] = false
  }

  const move = (data1) => {
    data1.forEach((item, index) => {
      if(item.dataIndex == key) {
        data1.splice(index, 1);

        checkData.value[item.parentKey] = (checkData.value[item.parentKey] || []).filter(k => k != key)
        isDelete == true
      }
      if(isDelete == false && item['children']) {
        move(item['children'])
      }
    })
  }
  
  move(columns.value)
  columns.value = columns.value.filter(i => {
    if(i.children) {
      return i.children.length != 0
    }
    return true 
  })

  refreshTree()
}

// 清空所有
const clearAllTable = () => {
  columns.value = [];
  checkData.value = {}
  checkAllData.value = []
  refreshTree()
}

// 弹窗关闭
const dialogClose = () => {
  checkAllData.value = {}
  checkData.value = {}
  columns.value = []
  emits('close')
}

// 回显数据
const echoInfo = () => {
  const cols = tableColStore.getCols
  columns.value = cloneDeep(cols)

  let flatCols = flatArr(cloneDeep(columns.value))

  let parentKeys = Array.from(new Set(flatCols.map(i => i.parentKey)));
  parentKeys.forEach(k => {
    checkData.value[k] = flatCols.filter(i => i.parentKey == k).map(i => i.dataIndex)
    
    let pItem = collapses.value.find(p => p.activeKey == k);
    if(pItem) {
      if(checkData.value[k].length == (pItem['els'] || []).length) {
        checkAllData.value[k] = true
      }
    }
  })
  refreshTree()
}

const flatArr = (data: any[]) => {
  let results = [];
  const flat = (data1) => {
    data1.forEach(item => {
      if((item.children || []).length != 0) {
        flat(item.children)
      }
      else {
        results.push(item)
      }
    })
  }
  flat(data)
  return results
}

watch(() => attrs.open, async (nval, oval) => {
  if (nval == true) {
    echoInfo()
  }
})
</script>

<style lang='scss' >
.u-personal-manager-edit {
  .ant-collapse-item-disabled {
    .ant-collapse-header {
      cursor: default;
      .ant-collapse-header-text {
        color: rgba(0, 0, 0, 0.88)
      }
    }
  }
}
.u-side-tree-custom {
  .ant-tree-switcher {
    display: none
  }
  .ant-tree-node-content-wrapper {
    position: relative;
    line-height: 32px ;
    &:hover {
      color: #1890ff;
      background-color: rgba(24, 144, 255, 0.2);
    }
    .ant-tree-iconEle {
      line-height: 32px ;
    }
    .ant-tree-title {
      font-size: 14px;
      padding-left: 6px
    }
    .u-tree-clear-icon {
      position: absolute;
      right: 20px;
      top: 50%;
      transform: translateY(-50%);
      font-size: 12px;
      color: #AAAAAA 
    }
  }
}
</style>